<template>
	<view class="combat">
		<canvas id="canvas" type='2d' height="212" width="242"></canvas>
	</view>
</template>

<script>
export default {
	props: {
		sourceData: {
			type: Array,
			default: () => []
		},
		maxVal: {
			type: Number,
			default: 0
		},
		currentVal: {
			type: Number,
			default: 0
		}
	},
	data() {
		this.ctx = null;
		this.canvas = null;
		this.originX = 0;		// x原点
		this.originY = 0;		// y原点
		this.startAngle = 0;	// 起始角度
		this.radius = 158;		// 半径
		this.startNum = 0;		
		this.endNum = 30;
		this.speed = 1;
		this.combatMaxVal = 0;		// 实例内最大值
		return {
			
		}
	},
	mounted() {
		this.init();
	},
	methods: {
		// 初始化
		async init() {
			const pixelRatio = await this.getSystemInfo();
			const query = wx.createSelectorQuery().in(this);
			query
				.select(`#canvas`)
				.fields({node: true, size: true})
				.exec( res => {
					let canvas = res[0].node;
					let ctx = canvas.getContext('2d');
					this.canvas = res[0];
					this.ctx = ctx;
					this.setUppixelRatio();
				})
		},
		// 设置图表信息
		async setUppixelRatio() {
			const pixelRatio = await this.getSystemInfo();
			const { canvas: res, ctx } = this;
			let canvas = res.node;
			// 放大canvas 解决模糊问题
			canvas.width = res.width * pixelRatio;
			canvas.height = res.height * pixelRatio;
			this.originX = canvas.width / 2;
			this.originY = canvas.height / 2;
			this.startAngle = Math.PI + Math.PI / this.sourceData.length;
			// 最大值分为若干等分
			this.combatMaxVal = this.maxVal / this.sourceData.length;
			this.fitAngle();
			// 缩小canvas
			ctx.scale(pixelRatio, pixelRatio);
		},
		// 旋转图表
		fitAngle() {
			const { ctx } = this;
			ctx.save();
			ctx.translate(this.originX, this.originY);
			ctx.rotate(-45 * Math.PI / 180);
			ctx.translate(-this.originX, -this.originY);
			this.drawLineLabelMarkers();
			this.drawFilContent();
			this.drawText();
			ctx.restore();
		},
		// 绘制图表
		drawLineLabelMarkers() {
			const { ctx, sourceData, originX, originY, radius } = this;
			ctx.font = "24px Arial";
			ctx.lineWidth = 2;
			ctx.strokeStyle = "#6AB0E4";
			ctx.fillStyle = '#395D81';
			let angle = this.startAngle;
			ctx.beginPath();
			for(let i = 0; i < sourceData.length + 1; i++) {
				// 计算角度 累加上一次的角度
				angle = angle + 2 * Math.PI / sourceData.length;
				let x = parseInt(originX + radius * Math.cos(angle));
				let y = originY + radius * Math.sin(angle);
				// 绘制外层线框
				ctx.lineTo(x, y);
				ctx.lineTo(originX, originY);
				ctx.lineTo(x, y);
				if(sourceData[i]) {
					ctx.save();
					ctx.translate(x, y);
					ctx.rotate(45 * Math.PI / 180);
					ctx.translate(-x, -y);
					this.drawMarkersText(sourceData[i].title, x, y);
					ctx.restore();
				}
			}
			ctx.closePath();
			ctx.stroke();
		},
		// 绘制文案
		drawMarkersText(title, x, y) {
			const { originX, originY, ctx } = this;
			if (x < originX && y <= originY) {
				ctx.fillText(title, x - 55, y + 8);
			}
			else if (x < originX && y >= originY) {
				ctx.fillText(title, x - 25, y + 28);
			}
			else if (x > originX && y <= originY) {
				ctx.fillText(title, x - 22, y - 10);
			} 
			else {
				ctx.fillText(title, x + 6, y + 10);
			}
		},
		// 绘制中心主体内容
		drawFilContent() {
			const { ctx, sourceData, originX, originY, radius, startNum, endNum, combatMaxVal, canvas } = this;
			ctx.fillStyle = '#6AB0E4';
			ctx.strokeStyle = '#6AB0E4';
			let angle = this.startAngle;
			ctx.beginPath();
			for(let i = 0; i < sourceData.length; i++) {
				let r = radius * (sourceData[i].value / sourceData[i].maxVal) * startNum / endNum;
				angle = angle + 2 * Math.PI / sourceData.length;
				let x = originX + r * Math.cos(angle);
				let y = originY + r * Math.sin(angle);
				ctx.lineTo(x, y);
				ctx.stroke();
			}
			ctx.closePath();
			ctx.globalAlpha = 0.3;
			ctx.fill();
			ctx.globalAlpha = 1;
			ctx.stroke();
			if (this.startNum < this.endNum) {
				this.startNum += 1;
				this.time = setTimeout( _ => {
					ctx.clearRect(0, 0, canvas.width, canvas.height);
					this.setUppixelRatio();
				}, this.speed *= 1);
			}
		},
		drawText() {
			const { originX, originY, ctx, currentVal } = this;
			ctx.save();
			ctx.translate(originX, originY);
			ctx.rotate(45 * Math.PI / 180);
			ctx.translate(-originX, -originY);
			ctx.font = "36px Arial";
			ctx.fillStyle = '#303133';
			ctx.fillText(currentVal, originX - ctx.measureText(currentVal).width / 2 , originY + 16);
			ctx.restore();
		},
		// 获取分辨率
		getSystemInfo() {
			return new Promise(resolve => {
				wx.getSystemInfo({
					success: cRes => {
						resolve(cRes ? cRes.pixelRatio : 2);
					}
				})
			})
		}
	}
}
</script>

<style lang="scss" scoped>
.combat, canvas {
	display: block;
	width: 100%;
	height: 100%;
}
</style>
